<?php
/**
 * Smart Library - Smart Framework
 * http://smart-framework.highet.eu
 *
 * @category   SmartL
 * @package    SmartL_DataBinder
 * @subpackage DataAdapter
 * @copyright  Copyright (c) 2005-2008 Smart Framework team - Stepan Sindelar, Vojtech Vit
 * @license    http://www.opensource.org/licenses/bsd-license.php	New BSD License
 */

/**
 * @see SmartL_DataBinder_DataAdapter_Object
 */
require_once 'SmartL/DataBinder/DataAdapter/Object.php';

/**
 * The binding on doctrine adapter is similar to binding on object adapter.
 * 
 * But there are some differences:
 * 
 * If you want to bind on collection of many to many or one to many use array('index'=>'some_index','name'=>'relationName')
 * or, if the many to many or one to many relation is not indexed, use only array('relationName'), 
 * for example the rule than would be: array(array('relationName')) for many to many or one to many and 
 * array('relation2Name') for one to one.
 * 
 * You cannot bind on relation which is not created yet. 
 * For example, if record user has one to one relation with record address and you create new
 * instance of user's record, than you cannot bind something to its relation address, because it is not created yet.
 * 
 * @package SmartL_DataBinder
 * @subpackage DataAdapter
 */
class SmartL_DataBinder_DataAdapter_Doctrine extends SmartL_DataBinder_DataAdapter_Object {
	/**
	 * @param string $name
	 * @param mixed $value
	 * @param Doctrine_Record $object
	 */
	protected function property($name, $value, $object) {
		if (is_array ( $name )) {
			$this->specialProperty ( $name, $value, $object );
		} elseif (is_string ( $name )) {
			if ($object->getTable ()->hasColumn ( $name ) or $object->getTable ()->hasRelation ( $name )) {
				if ($value !== null) {
					$object->$name = $value;
				}
				return $object->$name;
			} else {
				require_once 'SmartL/DataBinder/DataAdapter/Doctrine/Exception.php';
				throw new SmartL_DataBinder_DataAdapter_Doctrine_Exception ( "Record {get_class($object)} does not have column or relation {$name}." );
			}
		} else {
			require_once 'SmartL/DataBinder/DataAdapter/Doctrine/Exception.php';
			throw new SmartL_DataBinder_DataAdapter_Doctrine_Exception ( "Binding rule {$name} was not recognized by this data adapter." );
		}
	}
	
	public function specialProperty($name, $value, Doctrine_Record $object) {
		if ($object->getTable ()->hasRelation ( 'Translation' ) and isset ( $name ['name'] ) and isset ( $name ['index'] )) {
			if ($object->Translation->getTable ()->hasColumn ( $name ['name'] )) {
				if ($value !== null) {
					$object->Translation [$name ['index']]->$name ['name'] = $value;
				}
				return $object->Translation [$name ['index']]->$name ['name'];
			}
		}
		if (count ( $name ) == 1) {
			reset ( $name );
			$name = current ( $name );
			if ($object->getTable ()->hasRelation ( $name )) {
				$ref = &$object->$name;
				if ($value !== null) {
					$ref [] = $value;
				}
				return $ref;
			} else {
				require_once 'SmartL/DataBinder/DataAdapter/Doctrine/Exception.php';
				throw new SmartL_DataBinder_DataAdapter_Doctrine_Exception ( "Record {get_class($object)} does not have relation {$name}." );
			}
		} else {
			require_once 'SmartL/DataBinder/DataAdapter/Doctrine/Exception.php';
			throw new SmartL_DataBinder_DataAdapter_Doctrine_Exception ( "Binding rule {" . implode ( ';', $name ) . "} was not recognized by data adapter." );
		}
	}
}
